Scite Ext Man |
|
최근 버전(2006-11-10)에서는 리눅스 버전에서의 심각한 버그가 교정되었고 좀 더 튼튼한 체계를 사용하여 입력된 줄이 편집판에 있는지 아니면 출력판에 있는지 결정한다. 또한 '스크립트 재적재' (Ctrl+Shift+R)로 extman이 제어하는 루아 스크립트를 재적재할 수 있다. 예제들이 더 추가되었다: * prompt.lua는 루아 프롬프트로 간단한 상호대화를 제공한다. * select_string.lua는 더블-클릭으로 전체 문자열 (또는 주석)을 선택할 수 있다. * select_block.lua는폴드 라인 옆의 여백을 클릭하면 블록을 선택할 수 있다.
extman은 Files:wiki_insecure/editors/SciTE/extman.lua에 있고; 예제와 코드는 Files:wiki_insecure/editors/SciTE/extman.zip에 있다; 완전히 루아로 작성되었으며 최신 SciTE 배포본과 잘 작동한다.
SciTE Lua 인터페이스는 아주 강력하다. 그러나 현재 무거운 스크립트들을 서로 '사이 좋게' 실행시킬 방법이 없다. SciteBufferSwitch를 생각해 보자; OnOpen
,OnSwitchFile
그리고 OnUserListSelection
처리자는 모두 버퍼 변화를 추적하도록 오버라이드되고 드롭-다운 버퍼 리스트를 보여준다. 그런 스크립트는 이런 이벤트들을 감시할 필요가 있는 다른 스크립트에 방해가 된다.
extman을 사용하면, 이 스크립트는 다음과 같이 보인다 (함수 buffer_switch
는 똑같다)
scite_OnOpen(buffer_switch) scite_OnSwitchFile(buffer_switch) scite_Command 'Switch Buffer|do_buffer_list|Ctrl+J' function do_buffer_list() scite_UserListShow(buffers,2,scite.Open) end
(extman 최신 버전은 OnOpenSwitch
도 지원한다. 열거나 버퍼를 전환하여 파일이 활성화될 때 호출된다 switch_buffers.lua
예제를 한 번 보자)
내부적으로, extman은 처리자 리스트를 유지한다. 예를 들면, scite_OnOpen
은 OnOpen
이 호출할 처리자 리스트에 함수를 추가한다. 이제 또다른 스크립트가 OnOpen
이벤트를 완벽하게 청취할 수 있다. 충돌을 일으키지 않는다. 비슷하게scite_OnChar
, scite_OnSave
,
등등의 이벤트가 있다 - OnUserListSelection
만 제외되는데, 다르게 처리되기 때문이다.
표준 SciTE Lua 이벤트 말고도, extman은 OnWord
, OnEditorLine
그리고 OnOutputLine
을 제공한다. 기본 이벤트들 위에 건설되었고 편의를 위해 포함되었다.
다음은 extman을 위하여 재작성된 '게으른' 단어 교체 예제이다. OnWord
처리자는 테이블을 받는다. 필드는 word
, startp
, endp
, ch
로 구성되는데 각각 발견된 단어, 그의 최초 위치, 마지막 위치, 그리고 그 단어 뒤에서 바로 발견된 문자이다.
function on_word(w) local subst = word_substitute(w.word) if subst ~= w.word then editor:SetSel(w.startp-1,w.endp-1) local was_whitespace = string.find(w.ch,'%s') if was_whitespace then subst = subst..w.ch end editor:ReplaceSel(subst) local word_end = editor.CurrentPos if not was_whitespace then editor:GotoPos(word_end + 1) end end end scite_OnWord(on_word)
OnOutputLine
은 오직 줄이 출력판에 타자될 경우에만 촉발된다. 다음은 간단하지만 SciTE용으로 효과적인 루아 콘솔이다:
local prompt = '> ' print 'Scite/Lua' trace(prompt) scite_OnOutputLine (function (line) local sub = string.sub if sub(line,1,2) == prompt then line = sub(line,3) end if sub(line,1,1) == '=' then line = 'print('..sub(line,2)..')' end local f,err = loadstring(line,'local') if not f then print(err) else local ok,res = pcall(f) if ok then if res then print('result= '..res) end else print(res) end end trace(prompt) return true end)
OnEditorLine
는 비슷한 이벤트이다. 사용자가 편집판에 줄을 입력할 경우에 일어난다는 점만 제외하고 말이다. 한 가지 주요한 차이점은 절대로 정상적인 문자 처리를 간섭하지 않는다는 것이다. 타자되는 선언 등등을 얼마든지 추적 유지할 수 있다. 다음 예제는 상당히 이상하지만, 어떻게 단축키를 연산에 묶을 수 있는지 보여준다.
scite_Command 'AltX|do_altx_commands|Alt+X' function do_altx_commands() editor:BeginUndoAction() scite_OnChar('once',function (ch) editor:EndUndoAction() editor:Undo() if ch == 's' then print('ess') elseif ch == 'f' then editor:BeginUndoAction() scite_OnEditorLine(handle_line) end return true end) end
Alt+X를 타자하면, 이 함수는 한번-실행 OnChar
처리자를 설치한다. 오직 's' 또는 'f'에 관심이 있지만, 언제나 눌린 다음 문자를 '먹어 치운다'. Emacs 사용자는 그런 키 조합을 상당히 자연스럽다고 여기고, 아마도 Alt+Ctrl+Shift 조합보다 더 쉽게 타자할 것이다. OnChar
는 특수 문자를 무시한다. 그래서 기호와 구두점으로 제한된다. (내 손가락은 Borland 환경에서 Ctrl+Q 다음에 숫자를 누르면 표식이 이동한다는 것을 여전히 기억한다 - SciteNumberedBookmarks 참조).
Alt+X 다음에 'f'를 누르면 사용자가 버퍼에 파일이름을 입력할 수 있다! 파일이름은 editor:Undo
에 의해 즉시 제거된다 그리고 그 파일이 열린다.
local function handle_line(line) editor:EndUndoAction() editor:Undo() scite_OnEditorLine(handle_line,'remove') scite.Open(line) end
extman는 몇가지 유용한 편의 함수를 제공한다. (파일 접근 같은) 어떤 경우 루아 라이브러리에 없는 기능을 보완한다. (예를 들면) SciTE에 lfs (Lua File System)가 포함되어 있으면, 사용자는 구현이 바뀌더라도 계속 scite_Files
을 사용할 수 있다.
scite_UserListShow(list,start,fn)
는 간편하게 Scintilla 사용자 리스트에 접근하는 방법이다 - 사용자 리스트는 적절하게 가른 문자열 등등으로 구성된다. 리스트에 시작 지표를 지정할 수 있다 - 여기에서는 현재 버퍼를 보여주지 않기 위해 사용했다.
scite_GetProp(key,default)
는 props
의사-테이블을 살짝 감싼 래퍼이다. key
특성이 존재하지 않으면, props[key]
는 nil이 아니라 빈 문자열을 돌려준다; default
가 지정되지 않으면, 그 특성이 존재하지 않을 경우 이 함수는 실제로 nil을 돌려준다.
scite_Files(mask)
는 path+mask에 있는 모든 파일을 돌려준다 (예, "d:/downloads/scite_lua/*.lua" - 정사선은 윈도우즈에서도 허용된다). SciteOther 라이브러리가 발견되면, 조용한 Execute
를 사용하고, 그렇지 않으면 os.execute
를 사용한다.
scite_FileExists(f)
는 읽기를 위해 파일을 열 수 있으면 참을 돌려준다.
scite_dofile(f)
는 dofile
과 비슷하다. 단, 언제나 SciTE의 기본 홈에 상대적으로 파일을 적재하고, 조용하게 실패한다.
scite_Command(cmds)
는 루아 함수를 도구 메뉴 아이템과 단축키에 연계하는데 아주 유용한 함수이다. 거기에 문자열을 건네든가, 아니면 문자열 리스트를 건넨다; 문자열을 형태가 <name>|<function>|<shortcut>인데, 여기에서 <shortcut>은 선택적이다.
폴더 이름을 유지하면서 파일을 SciTE 디렉토리에 풀자. Extman은 메인 루아 시작 스크립트가 목표이다 (물론 다른 곳에 두어도 된다)
ext.lua.startup.script=$(SciteDefaultHome)/extman.lua
시작하면, 기본 홈 디렉토리인 scite_lua
디렉토리 안에서 확장자가 .lua인 모든 파일을 찾아본다. ext.lua.directory
로 다른 곳에 배치할 수도 있다.
이 파일들이 적재되므로 그 디렉토리에 extman.lua를 *두지 않아도 된다*! scite_Command
를 호출하여 함수들을 등록할 기회가 있다. 미리 다른 스크립트도 적재할 수도 있다. 그래서 scite_require()
가 추가되었다. 이 함수로 파일을 명시적으로 적재하면, extman은 그 파일이 적재되었다고 간주한다.
아래의 코드는 OnChar
에 대하여 루아 확장이 선택적으로 extman을 사용할 수 있다. extman-가능한 스크립트가 extman 없이도 여전히 잘 작동하도록 만든다.
먼저 처리자가 이미 존재하는지 살펴본다. 다음으로, scite_OnChar
같은 extman 함수가 없으면, 아주 간단한 교체가 만들어진다. 물론, 이렇게 extman을 테스트하는 것은 증명된 방법은 아니다. 나머지 코드는 그러면 아무 일도 없는 것처럼 extman 함수를 활용할 수 있다. 간단한 scite_OnChar
함수는 오직 처리자 하나만 다룰 수 있다; 더 복잡한 것은 예상하시겠지만 extman을 설치해야 한다.
if OnChar and not scite_OnChar then error("처리자를 여러 개 사용하고 싶다면 extman을 사용하세요") elseif not scite_OnChar then local _OnChar scite_OnChar = function(f, remove) if remove then _OnChar = nil else _OnChar = f end end OnChar = function(c) if _OnChar then return _OnChar(c) end end end
Extman은 훌륭하다. 그렇지만 scite가 scite_temp1 파일을 만들어 내는 곳을 통제하고 싶다. 보통 한 번 코드를 만들면 주석을 제거한 다음 extman에 방향전환해서 미리 만들어진 그 파일이 scite 실행 파일이 존재하는 디렉토리에 열리도록 만든다.
extman.zip에 따라오는 switch_headers.lua를 시험해 보려고 했다. SciTE 1.74를 사용했는데 문제가 있었다. 다음 줄을 바꾸어야 했다. 다음을:
for i,v in list do다음으로:
for i,v in pairs(list) do그리고 다음을:
for i,ext in extensions do다음으로 바꾸어야 했다:
for i,ext in pairs (extensions) do
9a10 > if string.find(f,'[\\/]$') then return end 11a13 > if (f ~= "") then 20a23 > end 30c33,35 < scite_UserListShow(buffers,2,scite.Open) --- > if (table.getn(buffers) > 0) then > scite_UserListShow(buffers,1,scite.Open) > end
scite_Files
가 *.lua
에 대하여 test.lua
와 test.lua~
에 모두 부합했고 둘 모두 적재했기 때문이다 (뒤의 파일이 앞의 파일을 오버라이드한다). 뒤의 파일은 Emacs가 저장한 임시 백업 사본이었다. 그리고 왜 편집한 test.lua
를 적재했는데 아무 효과도 미치지 않는지 알아내는데 시간이 좀 걸렸다. 윈도우즈에서는 dir *.*
을 사용하여 한 디렉토리의 모든 파일에 일치시키고 다음 그 리스트를 FileGlob에 있는 globtopattern
함수를 사용하여 걸러내기를 제안하는 바이다.
어쨌든, SciteDebug [1]는 extman.lua의 scite_Files
을 다르게 구현한다. scite_Popen
이 호출되는데, 사용가능성에 따라 spawner.popen
또는 os.execute
를 선택적으로 래핑한다. 그 목적이 무엇인지 잘 모르겠지만, 이 함수를 호출할 때 순간적으로 나타나는 DOS 명령어 창을 피하기 위한 것 같다. (적어도 내가 시험해 볼 때는 그랬다). extman.lua의 두 버전이 합쳐지면 유용할 것 같다. --DavidManura
다음은 연속 주석을 자동화하는 스크립트이다!
../scite_lua/ 폴더에 <filename>.lua으로 저장하고 SciTE를 재시작하자. (플랫폼에 상관없으리라 믿는다!)
--auto_continue_comments.lua --다음 참조 테이블에서 (나중에) 올바른 줄끝(eol) 표식을 결정한다 local eol_tbl = {[0]="\r\n", [1]="\r", [2]="\n"} function auto_continue_comment(line) -- 여러줄 주석 계속 local multi = line:match("^(%s*)==%s*$") if multi then --줄에 "=="이 있다, 여러줄 주석을 시작한다 local eol = eol_tbl[editor.EOLMode] editor:BeginUndoAction() editor:LineUp() editor:LineDelete() editor:AddText("--[=[" .. eol .. eol .. "--]=]" .. eol) editor:LineUp(); editor:LineUp() editor:AddText(multi) editor:EndUndoAction() -- 블록 주석 계속 elseif line:find("^%s*%-%-%s*$") then --줄이 오직 '--'이다, 주석을 끝낸다 editor:LineUp() editor:LineDelete() elseif line:find("^%s*%-%-") then --줄이 주석이다, 자동으로 주석을 계속한다 editor:AddText("-- ") end return false --다른 메쏘드들이 이벤트에 반응하도록 허용한다 end --extman에 처리자를 등록한다 scite_OnEditorLine(auto_continue_comment)
'--' 다음에 텍스트를 타자하다가, 엔터를 치면, 다음 줄에 '--'가 벌써 삽입된다! 원하지 않으면, 그냥 엔터를 한 번 더 치면 사라진다! '=='을 타자하고 엔터를 치면 여러줄 주석이 만들어지고 캐럿이 그 안에 위치한다! 영감을 주신 SirAlaran?에게 감사드린다. 샘플 세션은 아래를 보자. --PeterMacDonald
-- <- 다음에 텍스트가 오면 블록 주석을 시작한다 -- 줄이 오직 "--"일 때까지 계속한다 -- 탭이나 스페이스가 "-- some text" 앞에 있으면, -- 다음과 같이, 블록 주석 들여쓰기가 시작된다! --[=[ 줄에 다음과 같이 "=="를 입력하면: == 다음과 같이 여러줄 주석이 시작된다! --]=] --[=[ 탭이나 스페이스가 "==" 앞에 있으면 다음과 같이 여러줄 주석이 들여쓰기 된다! --]=]